package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.ImportData;
import com.ruoyi.business.mapper.ImportDataMapper;
import com.ruoyi.business.service.IImportDataService;
import com.ruoyi.business.vo.*;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 导入数据Service业务层处理
 * 
 * @author qiancheng
 * @date 2025-09-15
 */
@Service
public class ImportDataServiceImpl extends ServiceImpl<ImportDataMapper, ImportData> implements IImportDataService
{
    @Autowired
    private ImportDataMapper importDataMapper;

    /**
     * 查询导入数据
     * 
     * @param id 导入数据主键
     * @return 导入数据
     */
    @Override
    public ImportData selectImportDataById(Long id)
    {
        return importDataMapper.selectImportDataById(id);
    }

    /**
     * 查询导入数据列表
     * 
     * @param importData 导入数据
     * @return 导入数据
     */
    @Override
    public List<ImportData> selectImportDataList(ImportData importData)
    {
        return importDataMapper.selectImportDataList(importData);
    }

    /**
     * 新增导入数据
     * 
     * @param importData 导入数据
     * @return 结果
     */
    @Override
    public int insertImportData(ImportData importData)
    {
        importData.setCreateTime(DateUtils.getNowDate());
        return importDataMapper.insert(importData);
    }

    /**
     * 修改导入数据
     * 
     * @param importData 导入数据
     * @return 结果
     */
    @Override
    public int updateImportData(ImportData importData)
    {
        importData.setUpdateTime(DateUtils.getNowDate());
        return importDataMapper.updateImportData(importData);
    }

    /**
     * 批量删除导入数据
     * 
     * @param ids 需要删除的导入数据主键
     * @return 结果
     */
    @Override
    public int deleteImportDataByIds(Long[] ids)
    {
        return importDataMapper.deleteImportDataByIds(ids);
    }

    /**
     * 删除导入数据信息
     * 
     * @param id 导入数据主键
     * @return 结果
     */
    @Override
    public int deleteImportDataById(Long id)
    {
        return importDataMapper.deleteImportDataById(id);
    }

    /**
     * 导入数据
     * @param importDataList
     * @param updateSupport
     * @return
     */
    @Override
    public String importImportData(List<ImportData> importDataList, boolean updateSupport) {
        if (importDataList == null || importDataList.isEmpty()) {
            throw new ServiceException("导入数据不能为空！");
        }

        int successCount = 0;
        int updateCount = 0;

        for (ImportData data : importDataList) {
            // 根据 type + field1 + field2 判断数据是否已存在
            ImportData exist = importDataMapper.selectByUniqueKey(data.getType(),
                    data.getField1(),
//                    data.getField2(),
                    data.getImportDay(),
                    data.getStartTime(),
                    data.getEndTime());

            if (exist != null) {
                if (updateSupport) {
                    data.setId(exist.getId());
                    importDataMapper.updateById(data);
                    updateCount++;
                }
            } else {
                importDataMapper.insert(data);
                successCount++;
            }
        }

        return String.format("成功导入 %d 条数据，更新 %d 条数据", successCount, updateCount);
    }

    /**
     * 根据类型获取导入时间列表
     */
    @Override
    public List<String> getImportTimesByType(Integer type) {
        List<Date> dates = importDataMapper.selectImportTimesByType(type);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return dates.stream()
                .map(sdf::format)
                .collect(Collectors.toList());
    }

    /**
     * 根据导入时间获取实验时间范围
     * @param importTime 导入时间
     * @param type 数据类型
     * @return 实验时间范围 VO
     */
    @Override
    public List<ExperimentTimeRangeVO> getTimeRangeByImportTime(Date importTime, Integer type) {
        return importDataMapper.selectTimeRangeByImportTime(importTime, type);
    }

    /**
     * 根据type下载不同的Excel模板
     *
     * @param type 数据类型：1=均匀性，2=热学，3=热流，4=压力流量
     * @param response HttpServletResponse
     */
    @Override
    public void downloadTemplate(Integer type, HttpServletResponse response) throws IOException {
        String fileName;
        ExcelUtil<?> util;
        String sheetName;

        // 格式化当前时间
        String timeStamp = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());

        switch (type) {
            case 1:
                fileName = "均匀性数据导入模板_" + timeStamp + ".xlsx";
                sheetName = "均匀性数据";
                util = new ExcelUtil<>(LiquidLevelTemplateVo.class);
                break;
            case 2:
                fileName = "热学数据导入模板_" + timeStamp + ".xlsx";
                sheetName = "热学数据";
                util = new ExcelUtil<>(ThermalTemplateVo.class);
                break;
            case 3:
                fileName = "热流数据导入模板_" + timeStamp + ".xlsx";
                sheetName = "热流数据";
                util = new ExcelUtil<>(HeatFlowTemplateVo.class);
                break;
            default:
                throw new IllegalArgumentException("未知的type类型: " + type);
        }

        // 设置响应头，浏览器下载的文件名就是 fileName
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition",
                "attachment; filename=\"" + java.net.URLEncoder.encode(fileName, "UTF-8") + "\"");

        // 导出 Excel，直接写入 response 输出流
        util.exportExcel(response, Collections.emptyList(), sheetName);
    }


    /**
     * 查询导入数据并按 type 分组
     *
     * @param types 可选，数据类型列表
     * @param field1 可选，字段1过滤
     * @param field2 可选，字段2过滤
     * @param importDay 可选，导入日期过滤
     * @param startTime 可选，开始时间过滤
     * @param endTime 可选，结束时间过滤
     * @return 按 type 分组的导入数据 VO 列表
     */
    @Override
    public List<ImportDataGroupVO> selectImportDataGroupedByTypes(String types,
                                                                  String field1,
                                                                  String field2,
                                                                  Date importDay,
                                                                  String startTime,
                                                                  String endTime) {
        List<String> typeList = Arrays.asList(types.trim().split(","));
        // 1. 查询符合条件的数据
        List<ImportData> allData = importDataMapper.selectImportDataListByTypes(
                typeList, field1, field2, importDay, startTime, endTime
        );

        // 2. 按 type 分组
        Map<Integer, List<ImportData>> groupedMap = allData.stream()
                .collect(Collectors.groupingBy(ImportData::getType));

        // 3. 转成 VO 列表
        return groupedMap.entrySet().stream()
                .map(entry -> {
                    ImportDataGroupVO vo = new ImportDataGroupVO();
                    vo.setType(entry.getKey());
                    vo.setList(entry.getValue());
                    return vo;
                })
                .collect(Collectors.toList());
    }

    /**
     *富氧四级页面
     * @param typeList 可选，数据类型列表
     * @param importDay 可选，导入日期过滤
     * @param startTime 可选，开始时间过滤
     * @param endTime 可选，结束时间过滤
     * @return
     */
    @Override
    public List<ImportDataGroupVO> queryCombustionProperties(String typeList, Date importDay, String startTime, String endTime) {
        if (typeList == null || typeList.trim().isEmpty()) {
            throw new ServiceException("类型列表不能为空");
        }

        // 1. 解析输入的typeList（1、2、3、4）
        List<String> inputTypes = Arrays.asList(typeList.trim().split(","));

        // 2. 定义输入类型与实际数据类型的映射关系（直接使用Integer列表）
        Map<String, List<Integer>> typeMapping = new HashMap<>();
        typeMapping.put("1", Arrays.asList(4, 5));  // 1对应实际type=4、5
        typeMapping.put("2", Arrays.asList(6, 7, 8));        // 2对应实际type=6、7、8
        typeMapping.put("3", Arrays.asList(9, 10, 11));       // 3对应实际type=9、10、11
        typeMapping.put("4", Arrays.asList(12, 13,14));           // 4对应实际type=4、5（根据业务调整）

        // 3. 转换为实际需要查询的type列表（Integer类型）
        List<Integer> actualTypes = new ArrayList<>();
        for (String inputType : inputTypes) {
            List<Integer> mappedTypes = typeMapping.get(inputType);
            if (mappedTypes != null) {
                actualTypes.addAll(mappedTypes);
            }
        }

        if (actualTypes.isEmpty()) {
            throw new ServiceException("未找到有效的数据类型");
        }
        // 4. 将实际类型列表转换为字符串列表（适配mapper接口）
        List<String> actualTypeStrs = actualTypes.stream()
                .map(String::valueOf)
                .collect(Collectors.toList());
        // 1. 查询符合条件的数据
        List<ImportData> allData = importDataMapper.selectImportDataListByTypes(
                actualTypeStrs, "", "", importDay, startTime, endTime
        );

        // 2. 按 type 分组
        Map<Integer, List<ImportData>> groupedMap = allData.stream()
                .collect(Collectors.groupingBy(ImportData::getType));

        // 3. 转成 VO 列表
        return groupedMap.entrySet().stream()
                .map(entry -> {
                    ImportDataGroupVO vo = new ImportDataGroupVO();
                    vo.setType(entry.getKey());
                    vo.setList(entry.getValue());
                    return vo;
                })
                .collect(Collectors.toList());
    }

    /**
     * 立式四级页面
     * @param typeList 可选，数据类型列表
     * @param importDay 可选，导入日期过滤
     * @param startTime 可选，开始时间过滤
     * @param endTime 可选，结束时间过滤
     * @return 按 type 分组的导入数据 VO 列表
     */
    @Override
    public List<ImportDataGroupVO> getVertFourthInfo(String typeList, Date importDay, String startTime, String endTime) {
        if (typeList == null || typeList.trim().isEmpty()) {
            throw new ServiceException("类型列表不能为空");
        }

        // 1. 解析输入的typeList（1、2、3、4）
        List<String> inputTypes = Arrays.asList(typeList.trim().split(","));

        // 2. 定义输入类型与实际数据类型的映射关系（直接使用Integer列表）
        Map<String, List<Integer>> typeMapping = new HashMap<>();
        typeMapping.put("1", Arrays.asList(15, 16));
        typeMapping.put("2", Arrays.asList(17, 18));

        // 3. 转换为实际需要查询的type列表（Integer类型）
        List<Integer> actualTypes = new ArrayList<>();
        for (String inputType : inputTypes) {
            List<Integer> mappedTypes = typeMapping.get(inputType);
            if (mappedTypes != null) {
                actualTypes.addAll(mappedTypes);
            }
        }

        if (actualTypes.isEmpty()) {
            throw new ServiceException("未找到有效的数据类型");
        }
        // 4. 将实际类型列表转换为字符串列表（适配mapper接口）
        List<String> actualTypeStrs = actualTypes.stream()
                .map(String::valueOf)
                .collect(Collectors.toList());
        // 1. 查询符合条件的数据
        List<ImportData> allData = importDataMapper.selectImportDataListByTypes(
                actualTypeStrs, "", "", importDay, startTime, endTime
        );

        // 2. 按 type 分组
        Map<Integer, List<ImportData>> groupedMap = allData.stream()
                .collect(Collectors.groupingBy(ImportData::getType));

        // 3. 转成 VO 列表
        return groupedMap.entrySet().stream()
                .map(entry -> {
                    ImportDataGroupVO vo = new ImportDataGroupVO();
                    vo.setType(entry.getKey());
                    vo.setList(entry.getValue());
                    return vo;
                })
                .collect(Collectors.toList());
    }

}
